`timescale 1ps/1ps
(* DowngradeIPIdentifiedWarnings="yes" *)
`include "top_define.v"

module MAC2NP_TOP
(

    
    input           rx_core_clk       ,//clk from mac
    input           user_rx_resetn    ,//resetn from mac

    input  [ 9:0]   ram_2p_cfg_register,
    input  [11:0]   ram_dp_cfg_register,

    input           rx_axis_tvalid      ,
    input  [63:0]   rx_axis_tdata       ,
    input           rx_axis_tlast       ,
    input  [ 7:0]   rx_axis_tkeep       ,
    //input  [89:0]   rx_axis_tuser       ,
    output          rx_axis_tready      ,
   
    output          tx_axis_tvalid      ,
    output [63:0]   tx_axis_tdata       ,
    output          tx_axis_tlast       ,
    output [ 7:0]   tx_axis_tkeep       ,
    // output [ 6:0]   tx_axis_tuser       ,
    input           tx_axis_tready      ,
   
    input       pkt_clk           ,
    input       pkt_rstn          ,
    
`ifdef SIM
  output wire         axi_valid_o,
  output wire [255:0] axi_data_o,
  output wire         axi_last_o,
  output wire [ 31:0] axi_keep_o,
  input  wire         axi_ready_o,

  input  wire         axi_valid_i,
  input  wire [255:0] axi_data_i,
  input  wire         axi_last_i,
  input  wire [ 31:0] axi_keep_i,
  output wire         axi_ready_i,
`endif
    
 input            pkt_rdy     ,
 output [255:0]   pkt_data_o  ,          
 output           pkt_eop_o   ,                      
 output [4:0]     pkt_mod_o   ,             
 output           pkt_sop_o   ,
 output           pkt_dval_o  ,
 output           pkt_dsav_o  ,
 input [255:0]   pkt_data_i  ,          
 input           pkt_eop_i   ,                      
 input [4:0]     pkt_mod_i   ,             
 //input           pkt_sop_i   ,             
 input           pkt_dval_i  ,
 output          pkt_rdy_o   ,
 input  wire     testmode     // DFT port
  );
// reg pkt_rstn_d1;
// reg pkt_rstn_d2;

//out
(*mark_debug = "true"*) wire         rx_axis_tvalid_1     ;
(*mark_debug = "true"*) wire [255:0] rx_axis_tdata_1      ;
(*mark_debug = "true"*) wire         rx_axis_tlast_1      ;
(*mark_debug = "true"*) wire [31:0]  rx_axis_tkeep_1      ;
(*mark_debug = "true"*) wire         rx_axis_tready_1     ;

//axi_fifo_rx 
(*mark_debug = "true"*) wire         rx_axis_tvalid_2     ;
(*mark_debug = "true"*) wire [255:0] rx_axis_tdata_2      ;
(*mark_debug = "true"*) wire         rx_axis_tlast_2      ;
(*mark_debug = "true"*) wire [31:0]  rx_axis_tkeep_2      ;

//axi_2_ll  
(*mark_debug = "true"*) wire [255:0]   pkt_rx_data  ;          
(*mark_debug = "true"*) wire           pkt_rx_eop   ;                      
(*mark_debug = "true"*) wire [4:0]     pkt_rx_mod   ;             
(*mark_debug = "true"*) wire           pkt_rx_sop   ;             
(*mark_debug = "true"*) wire           pkt_rx_dval  ;
///*(*mark_debug = "true"*)*/ wire           pkt_rx_dicard;

//frame_check
 (*mark_debug = "true"*) wire [255:0]   pkt_fc_data  ;          
 (*mark_debug = "true"*) wire           pkt_fc_eop   ;                      
 (*mark_debug = "true"*) wire [4:0]     pkt_fc_mod   ;             
 (*mark_debug = "true"*) wire           pkt_fc_sop   ;             
 (*mark_debug = "true"*) wire           pkt_fc_dval  ;
 (*mark_debug = "true"*) wire           pkt_fc_dsav  ;
 (*mark_debug = "true"*) wire           fc_full   ;




//ll_2_axi
(*mark_debug = "true"*) wire         tx_axis_tvalid_1     ;
(*mark_debug = "true"*) wire [255:0] tx_axis_tdata_1      ;
(*mark_debug = "true"*) wire         tx_axis_tlast_1      ;
(*mark_debug = "true"*) wire [31:0]  tx_axis_tkeep_1      ;
wire tx_axis_tready_1 ;

//axi_fifo_tx
// /*(*mark_debug = "true"*)*/ wire         tx_axis_tvalid_2     ;
// /*(*mark_debug = "true"*)*/ wire [255:0] tx_axis_tdata_2      ;
// /*(*mark_debug = "true"*)*/ wire         tx_axis_tlast_2      ;
// /*(*mark_debug = "true"*)*/ wire [31:0]  tx_axis_tkeep_2      ;
// wire tx_axis_tuser_2      ; 
// wire tx_axis_tready_2     ; 
//ASIC MAC
axis_conv_rx_40 U_axis_conv_rx_40(
    .ram_2p_cfg_register(ram_2p_cfg_register),
    .ram_dp_cfg_register(ram_dp_cfg_register),
    .m_axis_areset                (user_rx_resetn    ),
    .m_axis_aclk                  (rx_core_clk       ),
    
    .m_axis_rtvalid               (rx_axis_tvalid     ),
    .m_axis_rtready               (rx_axis_tready     ),
    .m_axis_rtdata                (rx_axis_tdata      ),
    .m_axis_rtkeep                (rx_axis_tkeep      ),
    .m_axis_rtlast                (rx_axis_tlast      ),
    
    .s_axis_aclk                  (pkt_clk             ),
    .s_axis_areset                (pkt_rstn            ),

    .s_axis_rtvalid               (rx_axis_tvalid_1     ),
    .s_axis_rtready               (rx_axis_tready_1     ), 
    .s_axis_rtdata                (rx_axis_tdata_1      ),
    .s_axis_rtkeep                (rx_axis_tkeep_1      ),
    .s_axis_rtlast                (rx_axis_tlast_1      )
    );   

axis_data_fifo U_axis_data_fifo_rx(
    .s_axis_aresetn      (pkt_rstn         ),
    .s_axis_aclk         (pkt_clk           ),
    .ram_2p_cfg_register(ram_2p_cfg_register),
    .s_axis_tvalid       (rx_axis_tvalid_1  ),
    .s_axis_tready       (rx_axis_tready_1  ),
    .s_axis_tdata        (rx_axis_tdata_1   ),
    .s_axis_tkeep        (rx_axis_tkeep_1   ),
    .s_axis_tlast        (rx_axis_tlast_1   ),

    .m_axis_tvalid       (rx_axis_tvalid_2  ),
    .m_axis_tready       (1'b1              ),
    .m_axis_tdata        (rx_axis_tdata_2   ),
    .m_axis_tkeep        (rx_axis_tkeep_2   ),
    .m_axis_tlast        (rx_axis_tlast_2   )
);

// assign tx_axis_tvalid_2 = (test_mode)? rx_axis_tvalid_2 : tx_axis_tvalid_1; 
// assign tx_axis_tdata_2  = (test_mode)? rx_axis_tdata_2  : tx_axis_tdata_1 ;
// assign tx_axis_tkeep_2  = (test_mode)? rx_axis_tkeep_2  : tx_axis_tkeep_1 ;
// assign tx_axis_tlast_2  = (test_mode)? rx_axis_tlast_2  : tx_axis_tlast_1 ;
// assign tx_axis_tready_1 = tx_axis_tready_2;

  //-------------------------------------------
  //DUT
  //-------------------------------------------
  //256 axi_stream_2_ll 
  axi_to_sop_eop U_axi_to_sop_eop(
      // .axi_clk              (/*rx_core_clk*/pkt_clk          ), //312.5MHZ
      .pkt_clk              (pkt_clk                ), //312.5MHZ
      .pkt_rst_n            (pkt_rstn               ),
      .ram_2p_cfg_register(ram_2p_cfg_register),
      // .axi_rst_n             
      //axi_clock axi_stream
      .in_axis_rdata        (/*rx_axis_tdata_1 */ rx_axis_tdata_2       ),
      .in_axis_rvalid       (/*rx_axis_tvalid_1*/ rx_axis_tvalid_2      ),
      .in_axis_rlast        (/*rx_axis_tlast_1 */ rx_axis_tlast_2       ),
      .in_axis_rkeep        (/*rx_axis_tkeep_1 */ rx_axis_tkeep_2       ),

      //pkt_clock 
      .pkt_rx_data          (pkt_rx_data            ),
      .pkt_rx_eop           (pkt_rx_eop             ),
      .pkt_rx_mod           (pkt_rx_mod             ),
      .pkt_rx_sop           (pkt_rx_sop             ),
      .pkt_rx_dval          (pkt_rx_dval            ),
      .i_discard            (/*pkt_rx_dicard*/ 1'b0 )
  );

//assign pkt_rx_dicard = ~((~fc_full) && pkt_rdy0);
// frame_check
    frame_check_256 #(
    .W_SIZE(10'd256),
    .MODE_SIZE(11'd5)
    )
  U_frame_check_256(
      .pkt_clk        (pkt_clk),
      .rst_n          (pkt_rstn),
      .ram_2p_cfg_register(ram_2p_cfg_register),
      .pkt_sop_i      (pkt_rx_sop),
      .pkt_eop_i      (pkt_rx_eop),
      .pkt_dval_i     (pkt_rx_dval),
      .pkt_data_i     (pkt_rx_data),
      .pkt_mod_i      (pkt_rx_mod),
      .pkt_eop_o      (pkt_fc_eop ),
      .pkt_sop_o      (pkt_fc_sop ),
      .pkt_dval_o     (pkt_fc_dval),
      .pkt_data_o     (pkt_fc_data),
      .pkt_mod_o      (pkt_fc_mod ),
      .pkt_dsav_o     (pkt_fc_dsav),
      .frame_check_rdy(pkt_rdy    ),
      .ram_full       (fc_full)
      );
assign pkt_eop_o      = pkt_fc_eop  ;
assign pkt_sop_o      = pkt_fc_sop  ;
assign pkt_dval_o   =   pkt_fc_dval ;
assign pkt_data_o   =   pkt_fc_data ;
assign pkt_mod_o      = pkt_fc_mod  ;
assign pkt_dsav_o   = pkt_fc_dsav   ;

//-------------------------------------------------

  //256 ll_2_axi_stream 
  sop_eop_to_axi U_sop_eop_to_axi(
      .clk                  (pkt_clk              ),
      .rst_n                (pkt_rstn             ),
      .ram_2p_cfg_register(ram_2p_cfg_register),

      //pkt_clock
      .pkt_tx_data          (pkt_data_i           ),
      .pkt_tx_eop           (pkt_eop_i            ),
      .pkt_tx_mod           (pkt_mod_i            ),
      //.pkt_tx_sop           (pkt_sop_i            ),
      .pkt_tx_dval          (pkt_dval_i           ),
      .pkt_tx_rdy           (pkt_rdy_o            ),

      // axi_clock axi_stream
      `ifdef SIM
      .out_axis_tready      (axi_ready_o       ),
      .out_axis_tdata       (axi_data_o        ),
      .out_axis_tvalid      (axi_valid_o       ),
      .out_axis_tkeep       (axi_keep_o        ),
      .out_axis_tlast       (axi_last_o        )
      `else
      .out_axis_tready      (tx_axis_tready_1       ),
      .out_axis_tdata       (tx_axis_tdata_1        ),
      .out_axis_tvalid      (tx_axis_tvalid_1       ),
      .out_axis_tkeep       (tx_axis_tkeep_1        ),
      .out_axis_tlast       (tx_axis_tlast_1        ) 
      `endif
  );

  //-------------------------------------------
  //-------------------------------------------

  axis_conv_tx_40 U_axis_conv_tx_40(
    .s_axis_areset           (pkt_rstn          ),
    .s_axis_aclk             (pkt_clk           ),
    .ram_dp_cfg_register(ram_dp_cfg_register),
    
  `ifdef SIM
    .s_axis_tvalid           (axi_valid_i   ),
    .s_axis_tready           (axi_ready_i   ),
    .s_axis_tdata            (axi_data_i    ),
    .s_axis_tkeep            (axi_keep_i    ),
    .s_axis_tlast            (axi_last_i    ),
  `else
    .s_axis_tvalid           (tx_axis_tvalid_1   ),
    .s_axis_tready           (tx_axis_tready_1   ),
    .s_axis_tdata            (tx_axis_tdata_1    ),
    .s_axis_tkeep            (tx_axis_tkeep_1    ),
    .s_axis_tlast            (tx_axis_tlast_1    ),
  `endif
    
    .m_axis_aclk             (rx_core_clk     ),
    .m_axis_areset           (user_rx_resetn  ),
    
    .m_axis_tvalid           (tx_axis_tvalid   ),
    .m_axis_tready           (tx_axis_tready   ),
    .m_axis_tdata            (tx_axis_tdata    ),
    .m_axis_tkeep            (tx_axis_tkeep    ),
    .m_axis_tlast            (tx_axis_tlast    )
    // .m_axis_tuser            (tx_axis_tuser    )
    );    

// always @(posedge rx_core_clk)begin
//     pkt_rstn_d1 <= pkt_rstn;
// end
// always @(posedge rx_core_clk)begin
//     pkt_rstn_d2 <= pkt_rstn_d1;
// end
// assign user_rx_resetn = testmode ? pkt_rstn : pkt_rstn_d2;// DFT port
// assign user_rx_resetn = pkt_rstn_d2;

endmodule
